/*
 * Copyright (c) 2017. Xi'an iRain IOT Technology service CO., Ltd (ShenZhen). All Rights Reserved.
 */

package com.parkingwang.keyboard.view;

import com.parkingwang.keyboard.HmsResourcesManager;
import com.parkingwang.keyboard.ResourceTable;
import com.parkingwang.keyboard.engine.KeyEntry;
import com.parkingwang.keyboard.engine.KeyType;
import com.parkingwang.keyboard.utils.Utils;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentState;
import ohos.agp.components.Text;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.multimodalinput.event.TouchEvent;

/**
 * @author 黄浩杭 (huanghaohang@parkingwang.com)
 * @since 2017-09-26 0.1
 */
public final class KeyView extends Text implements Component.TouchEventListener, Component.DrawTask {
    private HiLogLabel hiLogLabel = new HiLogLabel(HiLog.LOG_APP, 0x78002, KeyboardView.class.getSimpleName());
    private final BubbleDrawable mBubbleDrawable;
    private KeyEntry mBoundKey;

    private PixelMapElement mDeleteDrawable;
    private boolean mDrawPressedText = false;

    private boolean mShowBubble;
    private StateElement mOkKeyTintColor;

    public KeyView(Context context) {
        this(context, null);
    }

    public KeyView(Context context, AttrSet attrs) {
        super(context, attrs);
        setPadding(0, 0, 0, 0);
        setTextAlignment(TextAlignment.CENTER);
        mBubbleDrawable = new BubbleDrawable(context);
        mOkKeyTintColor = getMOKeyTintColor();
        setTouchEventListener(this::onTouchEvent);
        addDrawTask(this::onDraw);
        setClipEnabled(false);
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        HiLog.info(hiLogLabel, "setEnable = " + HiLog.getStackTrace(new Throwable()));
        if (!enabled) {
            setTextColor(new Color(Color.getIntColor("#CCCCCC")));
        } else {
            setTextColor(new Color(Color.getIntColor("#000000")));
        }

    }

    public void setBubbleTextColor(int bubbleTextColor) {
        mBubbleDrawable.setTextColor(bubbleTextColor);
    }

    public void setOkKeyTintColor(StateElement okKeyTintColor) {
        mOkKeyTintColor = okKeyTintColor;
    }

    public KeyEntry getBoundKey() {
        return mBoundKey;
    }

    public void bindKey(KeyEntry bindKey) {
        mBoundKey = bindKey;
        mDrawPressedText = false;
        if (bindKey.keyType == KeyType.FUNC_OK) {
            final PixelMapElement drawable = Utils.getPixelMapElement(getContext(), ResourceTable.Media_pwk_keyboard_key_general_bg_normal);
            final PixelMapElement tintDrawable = DrawableTint.tint(drawable, mOkKeyTintColor);
            setBackground(tintDrawable);

            setTextColor(Color.WHITE);
        } else {
            StateElement stateElement = new StateElement();
            int[] pressedList = new int[]{ComponentState.COMPONENT_STATE_PRESSED};
            PixelMapElement pixelMapElement = Utils.getPixelMapElement(getContext(), ResourceTable.Media_pwk_keyboard_key_general_bg_pressed);
            stateElement.addState(pressedList, pixelMapElement);

            int[] emptyList = new int[]{ComponentState.COMPONENT_STATE_EMPTY};
            PixelMapElement normalElement = Utils.getPixelMapElement(getContext(), ResourceTable.Media_pwk_keyboard_key_general_bg_normal);
            stateElement.addState(emptyList, normalElement);
            setBackground(stateElement);
        }
    }

    public void setShowBubble(boolean showBubble) {
        mShowBubble = showBubble;
    }

    @Override
    public void setText(String text) {
        super.setText(text);
        HiLog.info(hiLogLabel, "setText text = " + text);
        if (mBubbleDrawable != null) {
            mBubbleDrawable.setText(String.valueOf(text));
        }
    }

    private void drawDeleteKey(Canvas canvas) {
        if (mDeleteDrawable == null) {
            mDeleteDrawable = Utils.getPixelMapElement(getContext(), ResourceTable.Media_pwk_key_delete);
            mDeleteDrawable.setBounds(0, 0, mDeleteDrawable.getWidth(), mDeleteDrawable.getHeight());
        }
        canvas.save();
        canvas.translate((getWidth() - mDeleteDrawable.getWidth()) / 2f,
                (getHeight() - mDeleteDrawable.getHeight()) / 2f);

        mDeleteDrawable.drawToCanvas(canvas);
        canvas.restore();
    }

    private StateElement getMOKeyTintColor() {
        StateElement stateElement = new StateElement();
        int[] disableStateList = new int[]{ComponentState.COMPONENT_STATE_DISABLED};
        ShapeElement disableElement = new ShapeElement();
        disableElement.setRgbColor(RgbColor.fromArgbInt(Color.getIntColor("#090909")));
        stateElement.addState(disableStateList, disableElement);

        int[] pressStateList = new int[]{ComponentState.COMPONENT_STATE_PRESSED};
        ShapeElement pressElement = new ShapeElement();
        pressElement.setRgbColor(RgbColor.fromArgbInt(HmsResourcesManager.getColorValueByResources(getContext(), ResourceTable.Color_pwk_keyboard_primary_dark_color)));
        stateElement.addState(pressStateList, pressElement);

        int[] emptyStateList = new int[]{ComponentState.COMPONENT_STATE_EMPTY};
        ShapeElement emptyElement = new ShapeElement();
        emptyElement.setRgbColor(RgbColor.fromArgbInt(HmsResourcesManager.getColorValueByResources(getContext(), ResourceTable.Color_pwk_keyboard_primary_color)));
        stateElement.addState(emptyStateList, emptyElement);
        return stateElement;
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent event) {
        if (!mShowBubble || !isEnabled()) {
            return false;
        }
        int action = event.getAction();
        if (action == TouchEvent.PRIMARY_POINT_DOWN) {
            mDrawPressedText = true;
            invalidate();
            return true;
        } else if (action == TouchEvent.PRIMARY_POINT_UP || action == TouchEvent.CANCEL) {
            mDrawPressedText = false;
            invalidate();
        }
        return false;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        KeyEntry keyEntry = mBoundKey;
        if (keyEntry == null) {
            return;
        }

        if (keyEntry.keyType == KeyType.FUNC_DELETE) {
            drawDeleteKey(canvas);
        } else if (keyEntry.keyType == KeyType.GENERAL && mDrawPressedText) {
            canvas.save();
            canvas.translate((getWidth() - mBubbleDrawable.getIntrinsicWidth()) / 2f,
                    -mBubbleDrawable.getIntrinsicHeight());
            mBubbleDrawable.draw(canvas);
            canvas.restore();
        }
    }
}
